// 模拟实现抢票逻辑
#include <iostream>
#include <string>
#include <vector>
#include <pthread.h>
#include <unistd.h>
#include "Mutex.hpp"


// 加锁
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

// 共享资源 -- 火车票
int tickets = 10000;

class ThreadData
{
public:
    ThreadData(const std::string &threadname)
        : threadname_(threadname)
    {
    }
    ~ThreadData()
    {
    }

public:
    std::string threadname_;
};

// 购票逻辑
void *getTicket(void *args)
{
    // other code
    ThreadData *td = static_cast<ThreadData *>(args);
    while (true)
    {
        // 加个大括号 -- 将共享区单独拿出来
        {
            // lockguard是对象 随代码块的生命周期变化 -- 换言之就是随代码块构造和析构
            // 只要定义好了 就不用管了 这就是封装的好处
            LockGuard lockguard(&lock); // RAII风格的加锁

            // 在共享区加锁
            // pthread_mutex_lock(&lock);

            if (tickets > 0)
            {
                // 值得抢
                usleep(1000);
                std::cout << td->threadname_ << " 正在进行抢票: " << tickets << std::endl;
                tickets--;

                // 解锁
                // pthread_mutex_unlock(&lock);
            }
            else
            {
                // 解锁
                // pthread_mutex_unlock(&lock);
                break;
            }
        }
        // 抢完票后 -- 模拟形成订单
        usleep(1000);
    }
    // other code
    return nullptr;
}

int main()
{
#define NUM 4
    // 创建一批线程
    std::vector<pthread_t> tids(NUM);
    for (int i = 0; i < NUM; i++)
    {
        char buffer[64];
        snprintf(buffer, sizeof(buffer), "thread %d", i + 1);
        ThreadData *td = new ThreadData(buffer);
        pthread_create(&tids[i], nullptr, getTicket, td);
    }

    for (const auto &tid : tids)
    {
        pthread_join(tid, nullptr);
    }

    return 0;
}